<!--首页-->
<template>
  <div class="dashboard-container">
<!--    统计卡片-->
    <!-- 统计卡片 -->
    <el-row :gutter="20" class="stats-row" justify="center" style="margin-top: 20px;">
      <el-col :xs="24" :sm="12" :md="6" class="stats-col">
        <div class="stats-card">
          <el-icon class="icon" style="margin-left: 55px"><Document /></el-icon>
          <div class="numbers">
            <div class="count">{{ animatedStats.totalPapers }}</div>
            <div class="label">累计论文</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="24" :sm="12" :md="6" class="stats-col">
        <div class="stats-card">
          <el-icon class="icon" style="margin-left: 55px"><Collection /></el-icon>
          <div class="numbers">
            <div class="count">{{ animatedStats.totalTemplates }}</div>
            <div class="label">累计模版</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="24" :sm="12" :md="6" class="stats-col">
        <div class="stats-card">
          <el-icon class="icon" style="margin-left: 30px"><Connection /></el-icon>
          <div class="numbers">
            <div class="count">{{ animatedStats.totalPass }}</div>
            <div class="label">总评分合格人数</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="24" :sm="12" :md="6" class="stats-col">
        <div class="stats-card">
          <el-icon class="icon" style="margin-left: 30px"><User /></el-icon>
          <div class="numbers">
            <div class="count">{{ animatedStats.activeUsers }}</div>
            <div class="label">活跃用户数</div>
          </div>
        </div>
      </el-col>
    </el-row>
<!--    图表区域-->
    <el-row :gutter="20" class="chart-row">
      <el-col :xs="24" :lg="12" class="chart-col">
        <div class="chart-box" id="weekly-uploads-chart" style="margin-top: -20px;"></div>
      </el-col>
      <el-col :xs="24" :lg="12" class="chart-col">
        <div class="chart-box" id="score-distribution-chart" style="margin-top: -20px;"></div>
      </el-col>
      <el-col :xs="24" :lg="24" class="chart-col" style="margin-top: 20px;">
        <div class="chart-box" id="score-student-sum-chart"></div>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import {ElIcon, ElMessage} from 'element-plus'
import { Document, Collection, Connection, User } from '@element-plus/icons-vue'
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as echarts from 'echarts'
import {
  getAdminHomeScoreStudentSum,
  getHomeOverview,
  getPaperScoreDistribution,
  getWeeklyPaperUploads
} from "../api/home.js";

/*
  统计卡片-数据获取
 */
// 统计数据
const stats = ref({
  totalPapers: 0,
  totalTemplates: 0,
  totalPass: 0,
  activeUsers: 0
})

// 统计数据动画
const animatedStats = ref({
  totalPapers: 0,
  totalTemplates: 0,
  totalPass: 0,
  activeUsers: 0
})

// 图表实例
let weeklyUploadsChart = null
let scoreDistributionChart = null
let scoreStudentSumChart = null
let resizeTimer = null


// 获取统计数据
const fetchBaseStats = async () => {
  try {
    // 获取上传论文总数、上传模版总数、合格人数、用户总数
    const res = await getHomeOverview()
    stats.value.totalPapers = res.data.totalPapers
    stats.value.totalTemplates = res.data.totalTemplates
    stats.value.totalPass = res.data.totalPass
    stats.value.activeUsers = res.data.activeUsers

    // 开始数字动画
    animateNumbers()
  } catch (error) {
    ElMessage.error('统计数据获取失败')
  }
}

// 数字滚动动画
const animateNumbers = () => {
  const duration = 2000 // 动画持续时间（毫秒）
  const steps = 50 // 动画步数
  const interval = duration / steps

  let currentStep = 0

  const timer = setInterval(() => {
    currentStep++
    const progress = currentStep / steps

    // 使用easeOutCubic缓动函数使动画更自然
    const easeProgress = 1 - Math.pow(1 - progress, 3)

    animatedStats.value.totalPapers = Math.floor(stats.value.totalPapers * easeProgress)
    animatedStats.value.totalTemplates = Math.floor(stats.value.totalTemplates * easeProgress)
    animatedStats.value.totalPass = Math.floor(stats.value.totalPass * easeProgress)
    animatedStats.value.activeUsers = Math.floor(stats.value.activeUsers * easeProgress)

    if (currentStep >= steps) {
      // 确保最终值与实际值完全一致
      animatedStats.value = { ...stats.value }
      clearInterval(timer)
    }
  }, interval)
}

// 初始化近七天论文上传情况折线图
const initWeeklyUploadsChart = async () => {
  try {
    const res = await getWeeklyPaperUploads()
    weeklyUploadsChart = echarts.init(document.getElementById('weekly-uploads-chart'))

    const weeklyUploadsData = res.data
    console.log('近七天论文上传情况接口返回数据:', weeklyUploadsData)

    // 处理数据
    const dates = weeklyUploadsData.map(item => item.uploadDate)
    const counts = weeklyUploadsData.map(item => item.paperCount)

    const option = {
      title: {
        text: '近七天论文上传情况',
        left: 'center',
        textStyle: {
          fontSize: 18,
          fontWeight: 'bold'
        }
      },
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(255, 255, 255, 0.9)',
        borderColor: '#ddd',
        borderWidth: 1,
        textStyle: { color: '#333' },
        formatter: function (params) {
          return `${params[0].name}: ${params[0].value} 篇`
        }
      },
      grid: {
        left: '5%',
        right: '5%',
        bottom: '10%',
        top: '15%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: dates,
        axisLabel: {
          rotate: 45,
          fontWeight: 'bold',
          margin: 10
        },
        axisTick: { alignWithLabel: true }
      },
      yAxis: {
        type: 'value',
        name: '上传数',
        nameLocation: 'middle',
        nameGap: 40,
        nameTextStyle: { fontWeight: 'bold' },
        splitLine: { lineStyle: { type: 'dashed' } }
      },
      series: [{
        type: 'line',
        data: counts,
        smooth: true, // 平滑曲线
        symbol: 'circle',
        symbolSize: 8,
        lineStyle: {
          width: 3,
          color: '#188df0'
        },
        itemStyle: {
          color: '#188df0',
          borderColor: '#83bff6',
          borderWidth: 2
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(131,191,246,0.6)' },
            { offset: 1, color: 'rgba(24,141,240,0.1)' }
          ])
        },
        animationDuration: 2000,
        animationEasing: 'elasticOut'
      }]
    }

    weeklyUploadsChart.setOption(option)

  } catch (e) {
    ElMessage.error('近七天论文上传情况获取失败')
  }
}
// 初始化各专业学生分数分布情况柱状-散点图
const initScoreDistributionChart = async () => {
  try {
    const res = await getPaperScoreDistribution()
    scoreDistributionChart = echarts.init(document.getElementById('score-distribution-chart'))

    const scoreDistributionData = res.data.data
    console.log('各专业学生分数分布情况接口返回数据:', res.data)

    const majors = res.data.majors

    // 转换数据格式
    const scatterData = scoreDistributionData.map(item => {
      const [majorIndex, score, jitter] = item
      return [majorIndex + jitter, score] // x轴位置+抖动，y轴是分数
    })

    const option = {
      title: {
        text: '各专业学生分数分布'
      },
      grid: {
        left: 80,
        right: 50
      },
      xAxis: {
        type: 'category',
        data: majors,
        boundaryGap: true
      },
      yAxis: {
        type: 'value',
        min: 0,
        max: 100, // 如果分数是 0-100
        name: '分数'
      },
      series: [
        {
          type: 'scatter',
          data: scatterData,
          itemStyle: {
            opacity: 0.4
          }
        }
      ]
    }

    scoreDistributionChart.setOption(option)

  } catch (e) {
    ElMessage.error('各专业学生分数分布情况获取失败')
  }
}
// 初始化各专业各分数段学生分布情况分组柱状图
const initScoreStudentSumChart = async () => {
  try {
    const res = await getAdminHomeScoreStudentSum()
    scoreStudentSumChart = echarts.init(document.getElementById('score-student-sum-chart'))

    const scoreStudentSumData = res.data
    console.log('各专业各分数段学生分布情况接口返回数据:', scoreStudentSumData)

    // 1. X轴：专业名称
    const majors = scoreStudentSumData.map(item => item.majorName)

    // 2. 各分数段的数组
    const data060 = scoreStudentSumData.map(item => item.count060)
    const data6080 = scoreStudentSumData.map(item => item.count6080)
    const data80100 = scoreStudentSumData.map(item => item.count80100)

    // 3. 构造柱状图配置
    const option = {
      title: {
        text: '各专业各分数段学生分布情况',
        left: 'center'
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' }
      },
      legend: {
        data: ['0-60分', '60-80分', '80-100分'],
        top: '10%'
      },
      grid: {
        left: '8%',
        right: '8%',
        bottom: '10%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: majors,
        axisTick: { alignWithLabel: true }
      },
      yAxis: {
        type: 'value',
        name: '学生人数',
        minInterval: 1,
        max: value => value.max + 2
      },
      series: [
        {
          name: '0-60分',
          type: 'bar',
          data: data060
        },
        {
          name: '60-80分',
          type: 'bar',
          data: data6080
        },
        {
          name: '80-100分',
          type: 'bar',
          data: data80100
        }
      ]
    }

    // 4. 渲染图表
    scoreStudentSumChart.setOption(option)
  } catch (e) {
    ElMessage.error('各专业各分数段学生分布情况获取失败')
  }
}

// 响应式调整图表
const handleResize = () => {
  if (resizeTimer) clearTimeout(resizeTimer)
  resizeTimer = setTimeout(() => {
    weeklyUploadsChart?.resize()
    scoreDistributionChart?.resize()
    scoreStudentSumChart?.resize()
  }, 200)
}


onMounted(async () => {
  await fetchBaseStats()
  await initWeeklyUploadsChart()
  await initScoreDistributionChart()
  await initScoreStudentSumChart()
  window.addEventListener('resize', handleResize)
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  weeklyUploadsChart?.dispose()
  scoreDistributionChart?.dispose()
  scoreStudentSumChart?.dispose()
})
</script>

<style scoped>
.dashboard-container {
  margin-top: -20px;
  background: #f5f7fa;
}

.stats-row {
  margin-bottom: 20px;
}

.stats-col {
  margin-bottom: 20px;
}

.stats-card {
  background: white;
  padding: 20px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  box-shadow: 0 4px 20px rgba(0,0,0,0.08);
  transition: all 0.4s ease;
  height: 100%;
}

.stats-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
}

.stats-card .icon {
  width: 60px;
  height: 60px;
  font-size: 32px;
  color: white;
  background: linear-gradient(135deg, #3ac29f 0%, #3a7bd5 100%);
  border-radius: 50%;
  padding: 14px;
  margin-right: 20px;
  transition: all 0.3s ease;
}

.stats-card:hover .icon {
  transform: scale(1.1) rotate(5deg);
}

.numbers .count {
  font-size: 28px;
  font-weight: 600;
  color: #303133;
  line-height: 1.2;
  transition: all 0.3s ease;
}

.stats-card:hover .numbers .count {
  color: #3a7bd5;
}

.numbers .label {
  color: #909399;
  font-size: 14px;
  margin-top: 8px;
}

.chart-row {
  margin-top: 30px;
}

.chart-box {
  background: white;
  padding: 20px;
  border-radius: 12px;
  height: 400px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.08);
  transition: all 0.3s ease;
}

.chart-box:hover {
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
}

.keywords-box {
  margin-top: 30px;
  background: white;
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.08);
  transition: all 0.3s ease;
}

.keywords-box:hover {
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
}

.keywords-box h3 {
  color: #303133;
  margin-bottom: 20px;
  font-weight: 600;
  text-align: center;
  position: relative;
  padding-bottom: 10px;
}

.keywords-box h3:after {
  content: '';
  position: absolute;
  width: 60px;
  height: 3px;
  background: linear-gradient(90deg, #3ac29f, #3a7bd5);
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

.stats-card, .chart-box, .keywords-box {
  animation: fadeIn 0.6s ease-out forwards;
}

.stats-col:nth-child(1) .stats-card { animation-delay: 0.1s; }
.stats-col:nth-child(2) .stats-card { animation-delay: 0.2s; }
.stats-col:nth-child(3) .stats-card { animation-delay: 0.3s; }
.stats-col:nth-child(4) .stats-card { animation-delay: 0.4s; }
.chart-col:nth-child(1) .chart-box { animation-delay: 0.5s; }
.chart-col:nth-child(2) .chart-box { animation-delay: 0.6s; }
.keywords-box { animation-delay: 0.7s; }
</style>
